package repository

import (
	"context"
	"fmt"
	"time"

	"github.com/google/uuid"
	"gorm.io/gorm"
	"techoiceness.com/aiagent/llm-gateway/internal/entity"
)

// userRepository 用户仓库实现
type userRepository struct {
	db *gorm.DB
}

// NewUserRepository 创建用户仓库
func NewUserRepository(db *gorm.DB) UserRepository {
	return &userRepository{
		db: db,
	}
}

// 用户认证相关
func (r *userRepository) GetUserByUsername(ctx context.Context, username string) (*entity.User, error) {
	var user entity.User
	err := r.db.WithContext(ctx).Where("username = ?", username).First(&user).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, nil
		}
		return nil, fmt.Errorf("failed to get user by username: %w", err)
	}
	return &user, nil
}

func (r *userRepository) GetUserByID(ctx context.Context, id uuid.UUID) (*entity.User, error) {
	var user entity.User
	err := r.db.WithContext(ctx).Where("id = ?", id).First(&user).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, nil
		}
		return nil, fmt.Errorf("failed to get user by ID: %w", err)
	}
	return &user, nil
}

// 用户管理
func (r *userRepository) CreateUser(ctx context.Context, user *entity.User) error {
	err := r.db.WithContext(ctx).Create(user).Error
	if err != nil {
		return fmt.Errorf("failed to create user: %w", err)
	}
	return nil
}

func (r *userRepository) UpdateUser(ctx context.Context, user *entity.User) error {
	err := r.db.WithContext(ctx).Save(user).Error
	if err != nil {
		return fmt.Errorf("failed to update user: %w", err)
	}
	return nil
}

func (r *userRepository) DeleteUser(ctx context.Context, id uuid.UUID) error {
	err := r.db.WithContext(ctx).Delete(&entity.User{}, "id = ?", id).Error
	if err != nil {
		return fmt.Errorf("failed to delete user: %w", err)
	}
	return nil
}

// 用户查询
func (r *userRepository) GetAllUsers(ctx context.Context, limit, offset int) ([]entity.User, int64, error) {
	var users []entity.User
	var total int64

	// 获取总数
	err := r.db.WithContext(ctx).Model(&entity.User{}).Count(&total).Error
	if err != nil {
		return nil, 0, fmt.Errorf("failed to count users: %w", err)
	}

	// 获取分页数据
	query := r.db.WithContext(ctx).Order("created_at DESC")
	if limit > 0 {
		query = query.Limit(limit)
	}
	if offset > 0 {
		query = query.Offset(offset)
	}

	err = query.Find(&users).Error
	if err != nil {
		return nil, 0, fmt.Errorf("failed to get users: %w", err)
	}

	return users, total, nil
}

func (r *userRepository) GetUsersByStatus(ctx context.Context, isActive bool, limit, offset int) ([]entity.User, int64, error) {
	var users []entity.User
	var total int64

	query := r.db.WithContext(ctx).Where("is_active = ?", isActive)

	// 获取总数
	err := query.Model(&entity.User{}).Count(&total).Error
	if err != nil {
		return nil, 0, fmt.Errorf("failed to count users by status: %w", err)
	}

	// 获取分页数据
	query = query.Order("created_at DESC")
	if limit > 0 {
		query = query.Limit(limit)
	}
	if offset > 0 {
		query = query.Offset(offset)
	}

	err = query.Find(&users).Error
	if err != nil {
		return nil, 0, fmt.Errorf("failed to get users by status: %w", err)
	}

	return users, total, nil
}

func (r *userRepository) SearchUsers(ctx context.Context, keyword string, limit, offset int) ([]entity.User, int64, error) {
	var users []entity.User
	var total int64

	query := r.db.WithContext(ctx).Where("username ILIKE ? OR email ILIKE ?", "%"+keyword+"%", "%"+keyword+"%")

	// 获取总数
	err := query.Model(&entity.User{}).Count(&total).Error
	if err != nil {
		return nil, 0, fmt.Errorf("failed to count users by keyword: %w", err)
	}

	// 获取分页数据
	query = query.Order("created_at DESC")
	if limit > 0 {
		query = query.Limit(limit)
	}
	if offset > 0 {
		query = query.Offset(offset)
	}

	err = query.Find(&users).Error
	if err != nil {
		return nil, 0, fmt.Errorf("failed to search users: %w", err)
	}

	return users, total, nil
}

// 用户统计
func (r *userRepository) GetUserCount(ctx context.Context) (int64, error) {
	var count int64
	err := r.db.WithContext(ctx).Model(&entity.User{}).Count(&count).Error
	if err != nil {
		return 0, fmt.Errorf("failed to get user count: %w", err)
	}
	return count, nil
}

func (r *userRepository) GetUserStats(ctx context.Context, userID uuid.UUID) (*UserStats, error) {
	var user entity.User
	err := r.db.WithContext(ctx).Where("id = ?", userID).First(&user).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, nil
		}
		return nil, fmt.Errorf("failed to get user: %w", err)
	}

	// 获取对话数量
	var conversationCount int64
	r.db.WithContext(ctx).Model(&entity.Conversation{}).Where("user_id = ?", userID).Count(&conversationCount)

	// 获取消息数量和token使用量
	var messageCount int64
	var totalTokens int64
	r.db.WithContext(ctx).Model(&entity.ClientMessage{}).Where("user_id = ?", userID).Count(&messageCount)
	r.db.WithContext(ctx).Model(&entity.ClientMessage{}).Where("user_id = ?", userID).Select("COALESCE(SUM(tokens_used), 0)").Scan(&totalTokens)

	// 获取最后活动时间
	var lastActivity time.Time
	r.db.WithContext(ctx).Model(&entity.ClientMessage{}).Where("user_id = ?", userID).Select("MAX(created_at)").Scan(&lastActivity)

	return &UserStats{
		UserID:            userID,
		ConversationCount: conversationCount,
		MessageCount:      messageCount,
		TotalTokensUsed:   totalTokens,
		LastActivity:      lastActivity,
		CreatedAt:         user.CreatedAt,
	}, nil
}
